今天我们讨论的是发布-观察者模式,也叫订阅模式,在javascript里,该模式要如何实现呢,首先我们先看一个现实生活中的例子
小明在工作几年后,准备买房结婚,于是他到售楼处,找售楼人员询问当前的价格,得知售楼价每平是小明好几个月工资的时候,小明犹豫了,于是他回去后,每天都给售楼处打电话,询问售楼人员的价格,售楼人员也会耐心解答,但是第二天又来了一个小芳,于是小芳每天也在打电话,时间久了,人越来越多,售楼人员每天接这么多电话,肯定吃不消要跳槽,当然我们只是举例子,现实情况是,售楼人员会留下小明,小芳等等人的电话存在花名册里,这就是订阅,然后等房价降下来的时候,售楼人员一个个打电话通知他们,这样双方都省了力气,订阅消息的人也拿到了应得的消息。现在假设花名册是 clientList <array>, 售楼处是salePart<object>,以此我们写一个简单发布-观察者模式的代码
var salePart = {} // 售楼处
var clientList = [] // 花名册
var xiaoming = {
name: '小明',
fn: function () {
var args = [].slice.call(arguments)
args.unshift(this.name)
console.log(args.join(','))
}
}
salePart.listen = function (person) { // 售楼处登记来访者的信息
clientList.push(person)
}
salePart.trigger = function (type, price) { // 售楼处通知来访者信息,type为售房面积,price为售房价格
if (clientList.length > 0) {
for (var i = 0, person; person = clientList[i++];) {
if (typeof person.fn === 'function') {
person.fn(type, price)
}
}
}
}
salePart.listen(xiaoming)
salePart.trigger('square80', 60000) // 打印出来 小明,square80,60000
下面小芳也要来看房,可是小芳比小明有钱的多,她要看的是200平米的房子,这样把小芳在添加进去的时候,售楼处就不能按照分类来进行通知他们的,200平米的房子的通知小明也能看到,这样小明会更扎心,万一不开心,就会损失一个潜在客户,所以我们还要完善一下上述代码,让售楼处可以按照房屋面积分别通知对应的买房者
var salePart = {} // 售楼处
var clientList = {} // 花名册
var xiaoming = {
name: '小明',
type: 's80',
fn: function () {
var args = [].slice.call(arguments)
args.unshift(this.name)
console.log(args.join(','))
}
}
var xiaofang = {
name: '小芳',
type: 's200',
fn: function () {
var args = [].slice.call(arguments)
args.unshift(this.name)
console.log(args.join(','))
}
}
salePart.listen = function (person) { // 售楼处登记来访者的信息
var type = person.type
if (!clientList[type] || clientList[type].length < 0) { // 原来的花名册先分类,然后再存入每个人的信息
clientList[type] = []
}
clientList[type].push(person)
}
salePart.trigger = function (type, price) { // 售楼处通知来访者信息,type为售房类型,price为售房价格
if (clientList[type] && clientList[type].length > 0) {
for (var i = 0, person; person = clientList[type][i++];) {
if (typeof person.fn === 'function') {
person.fn(type, price)
}
}
}
}
salePart.listen(xiaoming)
salePart.listen(xiaofang)
salePart.trigger('s80', 60000) // 打印出来 小明,square80,60000
salePart.trigger('s200', 200000) // 打印出来 小芳,square200,200000
可以看到,小明只能接收到80平米的房价信息,小芳呢,也只能看到200平米的房价信息,这样售楼处又回到了一片欣欣向荣的社会主义和谐景象,但是在实际开发中,上面的代码并不利于维护,因为很松散,我们可以用对象的方式来把代码重构一下
var SalePart = function () {
this.clientList = {}
}
SalePart.prototype.listen = function () { // 现在我们把该函数处理为可以一次接收多个来访者
var persons = [].slice.call(arguments)
for (var i = 0, p; p = persons[i++];) {
var type = p.type
if (!this.clientList[type] || this.clientList[type].length < 0) {
this.clientList[type] = []
}
this.clientList[type].push(p)
}
}
SalePart.prototype.trigger = function (type, price) {
if (this.clientList[type] && this.clientList[type].length > 0) {
for (var i = 0, p; p = this.clientList[type][i++];) {
if (typeof p.fn === 'function') {
p.fn(type, price)
}
}
}
}
var salePart = new SalePart()
salePart.listen(xiaoming, xiaofang)
salePart.trigger('s80', 50000) // 小明,s80,50000 感谢党和国家房价终于降了!
salePart.trigger('s200', 100000) // 小芳,s200,100000 这么便宜,买买买!!!
以上就是本章的内容,结合实际案例希望大家看起来更好理解一些,如有疑问,可以在下方留言,看到后我会尽快回复。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。